package
{
	import alternativa.engine3d.core.Camera3D;
	import alternativa.engine3d.core.Object3D;
	import alternativa.engine3d.core.Scene3D;
	import alternativa.engine3d.display.View;
	import alternativa.engine3d.materials.FillMaterial;
	import alternativa.types.Matrix3D;
	import alternativa.types.Point3D;
	
	import com.greensock.TweenLite;
	import com.tenoz.alternativa.utils.Transform;
	import com.tenoz.rubiks.RubiksCube;
	
	import flash.display.BlendMode;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	
	import net.hires.debug.Stats;

	[SWF (backgroundColor = "0x0", frameRate = "30", width = "465", height = "465")]
	public class Main extends Sprite
	{
		public const ROLL_UP:Point3D = Matrix3D.rotationMatrix(-Math.PI/2).getRotations();
		public const ROLL_DOWN:Point3D = Matrix3D.rotationMatrix(Math.PI/2).getRotations();
		public const ROLL_LEFT:Point3D = Matrix3D.rotationMatrix(0,Math.PI/2).getRotations();
		public const ROLL_RIGHT:Point3D = Matrix3D.rotationMatrix(0,-Math.PI/2).getRotations();
		
		private var view:View;
		private var scene:Scene3D;
		private var rubik:RubiksCube;
		private var spinObject:Object3D;
		
		private var red:FillMaterial = new FillMaterial(0xFF0000, 1, BlendMode.NORMAL);
		private var blue:FillMaterial = new FillMaterial(0x0000FF, 1, BlendMode.NORMAL);
		private var green:FillMaterial = new FillMaterial(0x00FF00, 1, BlendMode.NORMAL);
		private var yellow:FillMaterial = new FillMaterial(0xFFFF00, 1, BlendMode.NORMAL);
		private var white:FillMaterial = new FillMaterial(0xFFFFFF, 1, BlendMode.NORMAL);
		private var orange:FillMaterial = new FillMaterial(0xFF5500, 1, BlendMode.NORMAL);
		private var black:FillMaterial = new FillMaterial(0x000000, 1, BlendMode.NORMAL);
		
		private var roll:Point3D;
		private var inMotion:Boolean = false;
		
		public function Main()
		{
			addChild(new Stats());
			
			initScene();
			rubik = new RubiksCube();
			
			spinObject = new Object3D();
			spinObject.addChild(rubik);
			scene.root.addChild(spinObject);
			
			addEventListener(Event.ENTER_FRAME, onEnter);
			stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
		}
		
		private function initScene():void
		{
			scene = new Scene3D;
			scene.root = new Object3D();
			
			view = new View;
			view.camera = new Camera3D();
			
			scene.root.addChild (view.camera);
			
			view.width = view.height = 465;
			view.camera.z = -100;
			
			addChild (view);
		}
		
		private function onEnter(event:Event):void
		{
			scene.calculate();
		}
		
		private function onKeyUp(event:KeyboardEvent):void
		{
			if(inMotion) return;
			inMotion = true;
			
			switch(event.keyCode)
			{
			case Keyboard.UP:
				roll = ROLL_UP;
				break;
			case Keyboard.DOWN:
				roll = ROLL_DOWN;
				break;
			case Keyboard.LEFT:
				roll = ROLL_LEFT;
				break;
			case Keyboard.RIGHT:
				roll = ROLL_RIGHT;
				break;
			}
			
			TweenLite.to(spinObject, 1, {rotationX:roll.x, rotationY:roll.y, rotationZ:roll.z, onComplete:fixRotation});
		}
		
		private function fixRotation():void
		{
			Transform.setGlobalToLocalTransform(rubik);
			
			spinObject.rotationX = spinObject.rotationY = spinObject.rotationZ = 0;
			
			inMotion = false;
		}
		
		private function exacuteCommand(str:String):void
		{
			
		}
	}
}